package juc.mysynchronized;

/**
 * @ClassName SemaphoreExample
 * @PackageName juc.mysynchronized
 * @projectName myThread
 * @Description TODO
 * @Author games
 * @Date 2025/9/4 下午4:04
 * @Version 1.0
 */

import java.util.concurrent.Semaphore;

/**
 * 2. Semaphore（信号量，共享锁）
 * 应用场景：
 * <p>
 * 流量控制：限制对共享资源的并发访问数量。
 * 资源池：实现资源池，维护一组有限的共享资源。
 * 许可管理：维护一定数量的许可
 * 获取许可：线程执行前需要获取许可
 * 释放许可：线程执行后需要释放许可
 * 阻塞机制：当没有可用许可时，线程会被阻塞
 * <p>
 * <p>
 * // 创建指定许可数的信号量（非公平模式）
 * Semaphore semaphore1 = new Semaphore(3);
 * <p>
 * // 创建指定许可数的信号量，可选择公平模式
 * Semaphore semaphore2 = new Semaphore(3, true); // fair mode
 * Semaphore semaphore3 = new Semaphore(3, false); // non-fair mode (default)
 * <p>
 * 主要方法
 * 许可操作
 * acquire()：获取一个许可，没有许可时阻塞
 * acquire(int permits)：获取指定数量的许可
 * release()：释放一个许可
 * release(int permits)：释放指定数量的许可
 * 非阻塞操作
 * tryAcquire()：尝试获取一个许可，立即返回 true/false
 * tryAcquire(int permits)：尝试获取指定数量的许可
 * tryAcquire(long timeout, TimeUnit unit)：在指定时间内尝试获取许可
 * 查询方法
 * availablePermits()：返回当前可用的许可数
 * getQueueLength()：返回正在等待许可的线程数
 * hasQueuedThreads()：查询是否有线程正在等待许可
 */
public class SemaphoreExample {
    private final Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问

    public void accessResource() {
        try {
            semaphore.acquire(); // 获取一个许可
            System.out.println(Thread.currentThread().getName() + " is accessing resource.");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release(); // 释放一个许可
        }
    }

    public static void main(String[] args) {
        SemaphoreExample example = new SemaphoreExample();

        for (int i = 0; i < 5; i++) {
            new Thread(() -> example.accessResource()).start();
        }
    }
}

